﻿using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Net;
using Clarius.Silverlight.Streaming.Library;

namespace Clarius.Silverlight.VisualStudio.Tests
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class UnitTest1
    {
        const String serviceRoot = "https://silverlight.services.live.com";

        static Account accountWithSingleFileSet;
        static Account accountNonExistent;
        static Account accountInvalidServiceRoot;

        // README: you will need to have your own Silverlight Steaming account in order to run these tests against it

        // TODO: Please replace the account number below with your own valid account number
        static String accountNumber = "00000";
        // TODO: Please replace the account passkey below with your own valid account passkey
        static String accountPasskey = "00000000000000000000000000000000";

        static UnitTest1()
        {
            // this is valid data for an account containing just one app with two files
            accountWithSingleFileSet = new Account(accountNumber, accountPasskey, serviceRoot);
            // the following data is made up, should point to a non-existent account
            accountNonExistent = new Account("22222", "00000000000000000000000000000000", serviceRoot);
            // this is valid data for an account but uses an invalid service root
            accountInvalidServiceRoot = new Account(accountNumber, accountPasskey, "https://silverlightFOO.servicesBAR.live.com");
        }

        private static TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        [ClassInitialize]
        static public void FixtureInit(TestContext testContext)
        {
            AccountManager fsm = new AccountManager(accountWithSingleFileSet);
            if (fsm.GetFileSet("test1") == null)
            {
                fsm.UploadFileSet("test1", "testApp.zip");
            }
            if (fsm.GetFileSet("test2") == null)
            {
                fsm.UploadFileSet("test2", "testApp.zip");
            }
            if (fsm.GetFileSet("test3") == null)
            {
                fsm.UploadFileSet("test3", "testApp.zip");
            }
            if (fsm.GetFileSet("test4") == null)
            {
                fsm.UploadFileSet("test4", "testApp.zip");
            }
            if (fsm.GetFileSet("test5") == null)
            {
                fsm.UploadFileSet("test5", "testApp.zip");
            }
        }

        [TestMethod]
        public void CheckFileSetFileCount()
        {
            AccountManager fsm = new AccountManager(accountWithSingleFileSet);
            FileSet fs = fsm.GetFileSet("test1");
            Assert.AreEqual(fs.Count, 6);
        }

        [TestMethod]
        [ExpectedException(typeof(SilverlightStreamingException))]
        public void InvalidServiceRootShouldThrow()
        {
            AccountManager fsm = new AccountManager(accountInvalidServiceRoot);
            int count = fsm.FileSets.Count;
        }

        [TestMethod]
        public void CheckFileSetSize()
        {
            AccountManager fsm = new AccountManager(accountWithSingleFileSet);
            Assert.AreEqual<long>(235646, fsm.GetFileSet("test1").Size);
        }

        [TestMethod]
        [ExpectedException(typeof(SilverlightStreamingException))]
        public void UploadExistingFileSetShouldFail()
        {
            AccountManager fsm = new AccountManager(accountWithSingleFileSet, 100);
            fsm.UploadFileSet("ReplaceFileSet", "testApp.zip");
            fsm.UploadFileSet("ReplaceFileSet", "testApp.zip");
        }

        [TestMethod]
        public void UploadExistingFileSetWithOverwriteShouldNotFail()
        {
            AccountManager fsm = new AccountManager(accountWithSingleFileSet, 100);
            fsm.UploadFileSet("ReplaceFileSet", "testApp.zip", true);
            fsm.UploadFileSet("ReplaceFileSet", "testApp.zip", true);
        }

        [TestMethod]
        public void FileSetIsApplication()
        {
            AccountManager fsm = new AccountManager(accountWithSingleFileSet, 100);
            FileSet fs = fsm.GetFileSet("test1");
            Assert.AreEqual(true, fs.IsApplication);
        }

        [TestMethod]
        public void FileSetShouldContainManifestFile1()
        {
            AccountManager fsm = new AccountManager(accountWithSingleFileSet, 100);
            FileSet fs = fsm.GetFileSet("test1");
            File file = fs["manifest.xml"];
            Assert.IsNotNull(file);
        }

        [TestMethod]
        public void FileSetShouldContainManifestFile2()
        {
            bool found = false;
            AccountManager fsm = new AccountManager(accountWithSingleFileSet, 100);
            foreach (File file in fsm.FileSets[0].Files)
            {
                if (file.Name.ToLower() == "manifest.xml")
                {
                    found = true;
                }
            }

            Assert.IsTrue(found);
        }

        [TestMethod]
        [ExpectedException(typeof(SilverlightStreamingException))]
        public void InvalidAccountShouldThrow()
        {
            AccountManager fsm = new AccountManager(accountNonExistent, 100);
            FileSet fs = fsm.GetFileSet("test1");
            int c = fs.Count;
        }

        [TestMethod]
        public void RetrieveFileSetsWithPartialResults()
        {
            // specify 1 as the number of max items to be returned
            AccountManager fsm = new AccountManager(accountWithSingleFileSet,1);
            List<FileSet> fileSets = fsm.FileSets;

            // the returned set should contain only one fileset
            Assert.AreEqual(1, fileSets.Count);
        }

        [TestMethod]
        public void RetrieveFileSets()
        {
            AccountManager fsm = new AccountManager(accountWithSingleFileSet);
            List<FileSet> fileSets = fsm.FileSets;

            // TODO !!
            // you will need to modify the number '3' below to match the current number of file sets in your account
            // this is required so you can still run these tests against an account where you already have existing filesets
            // besides the ones created by these tests.
            Assert.AreEqual(3, fileSets.Count);
        }

        [TestMethod]
        public void NonExistentFileSetShouldReturnNull1()
        {
            // with default constructor which won't specify max-items
            AccountManager fsm = new AccountManager(accountWithSingleFileSet);
            FileSet fs = fsm.GetFileSet("InvalidFileSet");
            Assert.IsNull(fs);
        }

        [TestMethod]
        public void NonExistentFileSetShouldReturnNull2()
        {
            // with ctor for limiting the result list
            AccountManager fsm = new AccountManager(accountWithSingleFileSet, 100);
            FileSet fs = fsm.GetFileSet("InvalidFileSet");
            Assert.IsNull(fs);
        }

        [TestMethod]
        [ExpectedException(typeof(SilverlightStreamingException),"FileSet not found")]
        public void DeleteNonExistentFileSetShouldFail()
        {
            AccountManager fsm = new AccountManager(accountWithSingleFileSet);
            fsm.DeleteFileSet("NonExistentFileSetName");
        }

        [TestMethod]
        [ExpectedException(typeof(SilverlightStreamingException))]
        public void AccessingDeletedFileSetShouldThrow()
        {
            AccountManager fsm = new AccountManager(accountWithSingleFileSet);
            FileSet fs = fsm.GetFileSet("test4");
            fs.Delete();
            // the following line should throw as the FileSet was already deleted
            int c = fs.Count;
        }

        [TestMethod]
        [ExpectedException(typeof(SilverlightStreamingException))]
        public void AccessingDeletedFileShouldThrow()
        {
            AccountManager fsm = new AccountManager(accountWithSingleFileSet);
            FileSet fs = fsm.GetFileSet("test5");
            File f = fs["manifest.xml"];
            fs.Delete();
            // the following line should throw as the parent FileSet has been deleted
            String filename = f.Name;
        }

        [TestMethod]
        public void UploadAndDeleteFileSet()
        {
            AccountManager fsm = new AccountManager(accountWithSingleFileSet);
            String tempName = System.IO.Path.GetFileNameWithoutExtension(System.IO.Path.GetTempFileName());
            fsm.UploadFileSet(tempName, "testApp.zip");
            fsm.DeleteFileSet(tempName);
        }

        [TestMethod]
        public void DownloadTextFilesAndCheckFileSize()
        {
            AccountManager fsm = new AccountManager(accountWithSingleFileSet);
            String filename = System.IO.Path.GetTempFileName();

            FileSet fileSet = fsm.GetFileSet("test3");
            File file = fileSet["test3.xaml"];
            file.Download(file.Name);
            Assert.AreEqual(file.Size, new System.IO.FileInfo(file.Name).Length, "Remote and local file sizes doesn't match");
            file = fileSet["manifest.xml"];
            file.Download(file.Name);
            Assert.AreEqual(file.Size, new System.IO.FileInfo(file.Name).Length, "Remote and local file sizes doesn't match");
        }

        [TestMethod]
        public void DownloadBinaryFilesAndCheckFileSize()
        {
            AccountManager fsm = new AccountManager(accountWithSingleFileSet);

            FileSet fileSet = fsm.GetFileSet("test2");
            File file = fileSet["tortuga.png"];
            file.Download(file.Name);
            Assert.AreEqual(file.Size, new System.IO.FileInfo(file.Name).Length, "Remote and local file sizes doesn't match");
            file = fileSet["silver.jpg"];
            file.Download(file.Name);
            Assert.AreEqual(file.Size, new System.IO.FileInfo(file.Name).Length, "Remote and local file sizes doesn't match");
        }

        // Deletion of files is not yet supported by the Silverlight Streaming server

        //[TestMethod]
        //public void DeleteFile()
        //{
        //    AccountManager fsm = new AccountManager(accountWithSingleFileSet);

        //    FileSet fileSet = fsm.GetFileSet("test3");
        //    File file = fileSet["tortuga.png"];
        //    file.Delete();
        //}
    }
}
